package com.yc.service.impl;

import cn.hutool.core.util.StrUtil;
import com.yc.common.utils.AlyExcelUtil;
import com.yc.common.utils.DateUtil;
import com.yc.entity.User;
import com.yc.exception.BizException;
import com.yc.mapper.*;
import com.yc.common.utils.ValueUtils;
import com.yc.exception.CustomException;
import com.yc.service.UserService;
import com.yc.vo.AttendanceData;
import com.yc.vo.ScheduleVo;
import com.yc.vo.StudentAttendanceRecord;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.yc.entity.Schedule;
import com.yc.service.ScheduleService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;

/**
 * 课程表;(schedule)表服务实现类
 * @date : 2023-6-28
 */
@Service
public class ScheduleServiceImpl implements ScheduleService{
    @Resource
    private ScheduleMapper scheduleMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private ClassInfoMapper classInfoMapper;

    @Resource
    private UserService userService;

    @Resource
    private LeavereQuestsMapper leavereQuestsMapper;

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    SchoolYearMapper schoolYearMapper;

    private int a = 0; //用作计算saveOrUpdate执行了几次,每执行一次加一,如果a==0,则执行后面的部分代码,否则不执行
    private String time1 = ""; //用来记录第一次的课程时间
    private int id1=0; //用来记录第一次的id
    private int classtimeFlag = 0; //用来判断是否是由小节补全后变成的大节,0表示由小节->大节,1表示由大节->小节
    private String predate =""; //存储小节补全前的时间
    private String predate1 = "";//大节拆分成小节之前的时间
    private Integer classId = null;//用来存储班级id
    private int courseFlag = 0; // 课程是否存在flag,如果存在则为1,反之为0
    private Integer teacherId = null;
    private String courseName = ""; //课程名称
    private String classroom = ""; //教室
    private String classtime = ""; //课程节次
    private String year = ""; //学年
    private String randomColor = ""; //课表颜色
    private String week = ""; //星期
    private List<Schedule>  schedulesList = null;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Schedule queryById(Integer id){
        return scheduleMapper.selectById(id);
    }


    /**
     * 根据teacherId,上课时间查出课表Id
     * @param teacherId
     * @param classTime
     * @return
     */
    public Integer queryscheduleid(int teacherId,String classTime,String date,int cid){
        Integer scheduleid = scheduleMapper.querySchId(teacherId, classTime,date,cid);
        return scheduleid;
    }

    /**
     * 分页查询
     *
     * @param schedule 筛选条件
     * @param current 当前页码
     * @param size  每页大小
     * @return
     */
    @Override
    public Page<Schedule> paginQuery(Schedule schedule, long current, long size){
        //1. 构建动态查询条件
        LambdaQueryWrapper<Schedule>queryWrapper = new LambdaQueryWrapper<>();
        //2. 执行分页查询
        Page<Schedule> pagin = new Page<>(current , size , true);
        IPage<Schedule> selectResult = scheduleMapper.selectByPage(pagin , queryWrapper);
        pagin.setPages(selectResult.getPages());
        pagin.setTotal(selectResult.getTotal());
        pagin.setRecords(selectResult.getRecords());
        //3. 返回结果
        return pagin;
    }

    /**
     * 新增和修改数据
     *
     * @param schedule 实例对象
     * @return 实例对象
     */
    @Override
    public Schedule insert(Schedule schedule) throws BizException {
        a = 0;
        ValueUtils.check(ValueUtils.isEmpty(schedule.getCoursename()),"课程名称不能为空");
        ValueUtils.check(ValueUtils.isEmpty(schedule.getNickname()),"授课老师名称不能为空");
        final String[] splits = schedule.getNickname().split(" ");
        Integer teacherId = userMapper.selectIdByNickName(splits[0],splits[1]);
        ValueUtils.check(ValueUtils.isEmpty(schedule.getCname()),"班级名称不能为空");
        ValueUtils.check(ValueUtils.isEmpty(schedule.getDate()),"上课时间不能为空");
        ValueUtils.check(ValueUtils.isEmpty(schedule.getClasstime()),"上课时间不能为空");
        ValueUtils.check(ValueUtils.isEmpty(schedule.getClassroom()),"教室不能为空");
        ValueUtils.check(ValueUtils.isEmpty(schedule.getWeek()),"周次不能为空");


        //计算单双周
        String oddevenweek ="";
        if(schedule.getWeek()%2==0){
            oddevenweek = "双周";
        }else{
            oddevenweek = "单周";
        }


        //设置老师id
        schedule.setTeacherid(teacherId);
        //设置单双周
        schedule.setOddevenweek(oddevenweek);

        //颜色数组
        String[] colorCodes = {"#aaaaff", "#FDC123", "#D8F5AD", "#73E4CE", "#C8D14B", "#44C971", "#aaffff", "#00aaff", "#ffaaff", "#ffff7f", "#aaff7f", "#ffaa7f", "#7dffb8", "#ffc6c7", "#cbebff", "#ffb9ba"};
        //随机生成颜色
        Random random = new Random();
        int index = random.nextInt(colorCodes.length);
        String randomColor = colorCodes[index];
        schedule.setColour(randomColor);

        //虚拟数据
        schedule.setCreateBy("1"); // 创建人
        schedule.setUpdateBy("1"); // 更新的人
        schedule.setCreateTime(LocalDateTime.now()); //创建时间
        schedule.setUpdateTime(LocalDateTime.now()); //更新的时间

        // 1,2,3,4,5,6,7,8,9,10
        //格式化上课时间为1~2,3~4,5~6,7~8,9~10
        String date = schedule.getClasstime();
        final String[] dates = date.split(",");
        //先把字符串数组转成整型数组
        Integer [] dates1 = new Integer[dates.length];
        for (int i = 0; i < dates.length; i++) {
            dates1[i] = Integer.valueOf(dates[i]);
        }

        //节次数组升序
        Arrays.sort(dates1,new Comparator<Integer>(){
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
            }
        });

        //班级数组
        final String cname = schedule.getCname();
        String[] split=new String[]{cname};
        if (cname.indexOf(",")!=-1){
            split = cname.split(",");
        }


        //先执行一遍,判断是否有没有错，原因是,由于节次排序是正序排序的,
        // 现已知节次为34 由节次2改成1234 如果只执行一遍会出现节次2变成了节次12,但还是会提示异常信息,课程已经存在,加此判断是防止2变成12
        for (int d = 0; d<split.length;d++) {
            Integer classId = classInfoMapper.selectIdByCname(split[d]);
            //设置课程id
            schedule.setClassid(classId + "");
            int j = 0;
            for (int i = 0; i < ((dates1.length % 2 == 0) ? (dates1.length / 2) : dates1.length / 2 + 1); i++) {
                //该数字为奇数,且奇数+1 == 该偶数 即1,2-> 2 = 1+1,可以处理四位数,三位数中组成大节的数据,二位数组成大节的数据
                if (dates1[i + j] % 2 != 0 && i + 1 + j < dates1.length && dates1[i + 1 + j] == dates1[i + j] + 1) {
                    String str = dates1[i + j] + "~" + dates1[i + 1 + j];
                    j++;
                    schedule.setClasstime(str);
                    getTime(schedule);
                } else {
                    //处理小节数为2的,且这2小节不是相邻小节
                    if (dates1.length == 2) {
                        for (int k = 0; k < 2; k++) {
                            schedule.setClasstime(dates1[k] + "");
                            //设置上课时间
                            getTime(schedule);
                        }
                    } else {
                        //处理的是三位数的数据,如1,2,3->1和2已经存入数据库了,接下来就要处理3了
                        //也可以处理一位数的数据
                        schedule.setClasstime(dates1[i + j] + "");
                        //设置上课的具体时间
                        getTime(schedule);
                    }
                }
            }
        }

        //第二遍
        for (int d = 0; d<split.length;d++) {
            Integer classId = classInfoMapper.selectIdByCname(split[d]);
            //设置课程id
            schedule.setClassid(classId + "");
            int j = 0;
            for (int i = 0; i < ((dates1.length % 2 == 0) ? (dates1.length / 2) : dates1.length / 2 + 1); i++) {
                //该数字为奇数,且奇数+1 == 该偶数 即1,2-> 2 = 1+1,可以处理四位数,三位数中组成大节的数据,二位数组成大节的数据
                if (dates1[i + j] % 2 != 0 && i + 1 + j < dates1.length && dates1[i + 1 + j] == dates1[i + j] + 1) {
                    String str = dates1[i + j] + "~" + dates1[i + 1 + j];
                    j++;
                    schedule.setClasstime(str);
                    getTime(schedule);
                    //根据班级 周次 上课老师 课程名称 教室 去删除多余的数据, 如本来就有3了,然后通过修改其它的,导致多了课变成了3~4,那么这个3就必须删除
                    LambdaQueryWrapper <Schedule>wrapper1 = new LambdaQueryWrapper<>();
                    wrapper1.eq(Schedule::getWeek,schedule.getWeek());
                    wrapper1.eq(Schedule::getTeacherid,schedule.getTeacherid());
                    wrapper1.eq(Schedule::getCoursename,schedule.getCoursename());
                    wrapper1.eq(Schedule::getClassroom,schedule.getClassroom());
                    final List<Schedule> schedules = scheduleMapper.selectList(wrapper1);
                    final String[] split1 = schedule.getClasstime().split("~");
                    for (Schedule s : schedules) {
                        String classtime = s.getClasstime();
                        for (String s1 : split1) {
                            if (s1.equals(classtime)){
                                scheduleMapper.deleteById(s);
                            }
                        }
                    }
                    saveOrUpdate(schedule);
                } else {
                    //处理小节数为2的,且这2小节不是相邻小节
                    if (dates1.length == 2) {
                        for (int k = 0; k < 2; k++) {
                            schedule.setClasstime(dates1[k] + "");
                            int count = 0;
                            try{
                                getTime(schedule);
                                count++;
                            }catch (BizException e){

                            }
                            //设置上课时间
                            getTime(schedule);
                            saveOrUpdate(schedule);
                        }
                    } else {
                        //处理的是三位数的数据,如1,2,3->1和2已经存入数据库了,接下来就要处理3了
                        //也可以处理一位数的数据
                        schedule.setClasstime(dates1[i + j] + "");
                        //设置上课的具体时间
                        getTime(schedule);
                        saveOrUpdate(schedule);
                    }
                }
            }
        }
        return schedule;
    }

    /**
     * 补全时间
     * @param schedule
     * @throws BizException
     */
    private void getTime(Schedule schedule) throws BizException {

        String classTime = "";  //小节补全后的节次
        String newDate1 = calculateDate(schedule.getDate(), schedule.getClasstime());
        schedule.setDate(newDate1);
        String start = schedule.getDate();
        //如果该课程不含~,则补全之后再去数据库里面查找
        if (schedule.getClasstime().indexOf("~") == -1) {
            //单个的判断 -> 课程节次为3
            checkIsTrue(schedule,schedule.getClasstime());
            //单个变成多个的判断 如果课程节次为3,则改成3~4
            classTime = getClassTime(schedule);
            classtimeFlag = 1;
            checkIsTrue(schedule,classTime);
        }else {
            //判断大节
            checkIsTrue(schedule,schedule.getClasstime());
            predate1 = schedule.getDate();
            //判断小节
            final String[] split = schedule.getClasstime().split("~");
            for (int i = 0; i < split.length; i++) {
                classTime = split[i];
                checkIsTrue(schedule,classTime);
            }
        }
    }

    /**
     * 做一些判断,如老师是否已经有课,同一班级不能在同时间段添加
     * @param schedule
     * @param classTime
     * @throws BizException
     */
    private void checkIsTrue(Schedule schedule,String classTime) throws BizException {
        if (classtimeFlag==1){
            predate = schedule.getDate();
        }
        //设置上课的具体时间
        String newDate = calculateDate(schedule.getDate(), classTime);
        schedule.setDate(newDate);
        //schedule.getFlag().equals("0") 为0 就是添加
        if (schedule.getFlag().equals("0")){
            //根据上课时间和老师id去查询当前是否有课
            LambdaQueryWrapper<Schedule> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Schedule::getDate, schedule.getDate());
            wrapper.eq(Schedule::getTeacherid, schedule.getTeacherid());
            List<Schedule> list = scheduleMapper.selectList(wrapper);
            if (list.size() != 0) {
                for (int i = 0; i < list.size(); i++) {
                    //课程添加,如果教室，老师,时间相同,班级不相同,那就可以添加
                   if (list.get(i).getTeacherid().equals(schedule.getTeacherid())
                            && !(list.get(i).getClassroom().equals(schedule.getClassroom()))
                            && !(list.get(i).getClassid().equals(schedule.getClassid()))
                            && list.get(i).getDate().equals(schedule.getDate())){
                        throw new BizException("该时间段该老师已经有课了");
                    }
                }
            }
            //根据上课时间和班级id去查询当前是否有课
            LambdaQueryWrapper<Schedule> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Schedule::getDate, schedule.getDate());
            wrapper1.eq(Schedule::getClassid, schedule.getClassid());
            List<Schedule> list1 = scheduleMapper.selectList(wrapper1);
            if (list1.size() != 0) {
                for (int i = 0; i < list1.size(); i++) {
                    //对象的比较,比较他们的值,需要使用equals
                    if (list1.get(i).getClassid().equals(schedule.getClassid())
                        && list1.get(i).getDate().equals(schedule.getDate())) {
                        throw new BizException("该时间段该班级已经有课了");
                    }
                }
            }

            //根据上课时间和教室去查询当前是否有课
            LambdaQueryWrapper<Schedule> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(Schedule::getDate, schedule.getDate());
            wrapper2.eq(Schedule::getClassroom, schedule.getClassroom());
            List<Schedule> list2 = scheduleMapper.selectList(wrapper2);
            int count = 0;
            if (list2.size() != 0) {
                for (int i = 0; i < list2.size(); i++) {
                   if (list2.get(i).getClassroom().equals(schedule.getClassroom())
                            && list2.get(i).getDate().equals(schedule.getDate())
                            && !(list2.get(i).getTeacherid().equals(schedule.getTeacherid()))
                            && !(list2.get(i).getClassid().equals(schedule.getClassid()))) {
                        count++;
                        if (count==list2.size()){
                            throw new BizException("该时间段教室已经被占用了");
                        }
                    }
                }
            }

        }else {
            //根据上课时间和老师id去查询当前是否有课
            LambdaQueryWrapper<Schedule> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Schedule::getDate, newDate);
            wrapper.eq(Schedule::getTeacherid, schedule.getTeacherid());
            List<Schedule> list = scheduleMapper.selectList(wrapper);
            if (list.size() != 0) {
                int count1 =0;
                for (int i = 0; i < list.size(); i++) {
                    //对象的比较,比较他们的值,需要使用equals
                    if (!(list.get(i).getId().equals(schedule.getId()))
                            && list.get(i).getTeacherid().equals(schedule.getTeacherid())
                            && !(list.get(i).getClassroom().equals(schedule.getClassroom()))
                            && !(list.get(i).getClassid().equals(schedule.getClassid()))
                            && list.get(i).getDate().equals(schedule.getDate())) {
                           throw new BizException("该时间段该老师已经有课了");
                    }
                }
            }
            //根据上课时间和班级id去查询当前是否有课
            LambdaQueryWrapper<Schedule> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Schedule::getDate, newDate);
            wrapper1.eq(Schedule::getClassid, schedule.getClassid());
            List<Schedule> list1 = scheduleMapper.selectList(wrapper1);
            if (list1.size() != 0) {
                for (int i = 0; i < list1.size(); i++) {
                    //对象的比较,比较他们的值,需要使用equals
                    if (!(list1.get(i).getId().equals(schedule.getId()))
                        &&list1.get(i).getClassid().equals(schedule.getClassid())
                        &&list1.get(i).getDate().equals(schedule.getDate())) {
                        throw new BizException("该时间段该班级已经有课了");
                    }
                }
            }

            //根据上课时间和教室去查询当前是否有课
            LambdaQueryWrapper<Schedule> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(Schedule::getDate, newDate);
            wrapper2.eq(Schedule::getClassroom, schedule.getClassroom());
            List<Schedule> list2 = scheduleMapper.selectList(wrapper2);
            if (list2.size() != 0) {
                for (int i = 0; i < list2.size(); i++) {
                    //对象的比较,比较他们的值,需要使用equals
                    if (!(list2.get(i).getId().equals(schedule.getId()))
                        &&list2.get(i).getClassroom().equals(schedule.getClassroom())
                        && list2.get(i).getDate().equals(schedule.getDate())
                        && !(list2.get(i).getTeacherid().equals(schedule.getTeacherid()))
                        && !(list2.get(i).getClassid().equals(schedule.getClassid()))) {
                        throw new BizException("该时间段教室已经被占用了");
                    }
                }
            }
        }

    }

    /**
     * 封装更新和添加函数的一部分代码,主要执行修改和添加
     */
    private void saveOrUpdate(Schedule schedule) throws BizException {

        if (classtimeFlag ==1){
            schedule.setDate(predate);
        }

        if (predate1.indexOf("~")!=-1&&classtimeFlag!=1){
            schedule.setDate(predate1);
        }
        String start = schedule.getDate();
        if (start.indexOf("~")!=-1){
            start = start.split(" ")[0] + " " +start.split(" ")[1].split("~")[0]+":00";
        }
        final String now = (LocalDateTime.now().withNano(0) + "").replace("T", " ");
        long datePoor = DateUtil.getDatePoor(start, now);
        //根据时间来判断是否能进行删除
        if (datePoor>=0){
            throw  new BizException("时间不允许为过去时间");
        }

        //查询课程节次
        Integer id = schedule.getId();
        final Schedule schedule1 = scheduleMapper.selectById(id);
        String time = "";
        if (schedule1 != null) {
            time = schedule1.getClasstime();
        }

        if (a==0&&id!=null){
            time1 = time;
            id1 = id;
        }
        a++;

        //如果该课程存在id且课程节次与数据库的一致就是修改,否则就是添加
        if (schedule.getId() != null &&schedule.getFlag().equals("1")) {
            int count = 0;
            //如果包含~,可能是是由节次1->1~2,或者节次没变或者变成了3~4等等都有可能
            if (schedule.getClasstime().indexOf("~")!=-1){
                final String[] split = schedule.getClasstime().split("~");
                for (int i = 0; i < split.length; i++) {
                    if (split[i].equals(time1)){
                        scheduleMapper.deleteById(id1);
                        schedule.setId(null);
                        scheduleMapper.insert(schedule);
                    }else {
                        count++;
                    }
                }
                if (count==split.length){
                    scheduleMapper.deleteById(id1);
                    schedule.setId(null);
                    scheduleMapper.insert(schedule);
                }
            }else{
                //如果id1与id的值不同就执行添加
                if (id1!=id){
                    schedule.setId(null);
                    scheduleMapper.insert(schedule);
                }else {
                    //如果是先执行更新,则更新后需修改time1和id1的值
                    scheduleMapper.updateById(schedule);
                    if (a==1){
                        time1 = schedule.getClasstime();
                        id1 = -1;
                    }
                }
            }
        } else {
            schedule.setId(null);
            scheduleMapper.insert(schedule);
        }
    }

    /**
     * 补全课程节次,判断该节点是否有课
     * @param schedule
     * @return
     */
    private String getClassTime(Schedule schedule){
        String t ="";
        if (schedule.getClasstime().equals("1")){
            t = schedule.getClasstime()+"~2";
        }else if (schedule.getClasstime().equals("2")){
            t = 1+"~"+schedule.getClasstime();
        }else if (schedule.getClasstime().equals("3")){
            t = schedule.getClasstime()+"~4";
        }else if (schedule.getClasstime().equals("4")){
            t = "3~"+schedule.getClasstime();
        }else if (schedule.getClasstime().equals("5")){
            t = schedule.getClasstime()+"~6";
        }else if (schedule.getClasstime().equals("6")){
            t = "5~"+schedule.getClasstime();
        }else if (schedule.getClasstime().equals("7")){
            t = schedule.getClasstime()+"~8";
        }else if (schedule.getClasstime().equals("8")){
            t = "7~"+schedule.getClasstime();
        }else if (schedule.getClasstime().equals("9")){
            t = schedule.getClasstime()+"~10";
        }else if (schedule.getClasstime().equals("10")){
            t = "9~"+schedule.getClasstime();
        }
        return t;
    }

    /**
     * 计算日期
     * @param date
     * @param classtime
     * @return
     */
    private String calculateDate(String date,String classtime){
        String newStr = date.substring(0,date.lastIndexOf("-") + 3);
        String str ="";
        if ("1~2".equals(classtime)){
            str = "8:30~10:05";
        } else if ("3~4".equals(classtime)){
            str = "10:25~12:00";
        } else if ("5~6".equals(classtime)){
            str = "14:00~15:35";
        } else if ("7~8".equals(classtime)){
            str = "15:55~17:30";
        } else if ("9~10".equals(classtime)){
            str = "19:00~20:35";
        } else if ("1".equals(classtime)){
            str = "8:30~9:15";
        } else if ("2".equals(classtime)){
            str = "9:20~10:05";
        } else if ("3".equals(classtime)){
            str = "10:25~11:10";
        } else if ("4".equals(classtime)){
            str = "11:15~12:00";
        } else if ("5".equals(classtime)){
            str = "14:00~14:45";
        } else if ("6".equals(classtime)){
            str = "14:50~15:35";
        } else if ("7".equals(classtime)){
            str = "15:55~16:40";
        } else if ("8".equals(classtime)){
            str = "16:45~17:30";
        } else if ("9".equals(classtime)){
            str = "19:00~19:45";
        } else if ("10".equals(classtime)){
            str = "19:50~20:35";
        }
        return newStr + " " + str;
    }

    /**
     * 更新数据
     *
     * @param schedule 实例对象
     * @return 实例对象
     */

    @Override
    public Schedule update(Schedule schedule){
        //1. 根据条件动态更新
        LambdaUpdateChainWrapper<Schedule> chainWrapper = new LambdaUpdateChainWrapper<Schedule>(scheduleMapper);
        if(StrUtil.isNotBlank(schedule.getOddevenweek())){
            chainWrapper.set(Schedule::getOddevenweek, schedule.getOddevenweek());
        }
        if(StrUtil.isNotBlank(schedule.getClassid())){
            chainWrapper.set(Schedule::getClassid, schedule.getClassid());
        }
        if(StrUtil.isNotBlank(schedule.getClassroom())){
            chainWrapper.set(Schedule::getClassroom, schedule.getClassroom());
        }
        if(StrUtil.isNotBlank(schedule.getCoursename())){
            chainWrapper.set(Schedule::getCoursename, schedule.getCoursename());
        }
        if(StrUtil.isNotBlank(schedule.getClasstime())){
            chainWrapper.set(Schedule::getClasstime, schedule.getClasstime());
        }
        if(StrUtil.isNotBlank(schedule.getTeacherid()+"")){
            chainWrapper.set(Schedule::getTeacherid, schedule.getTeacherid());
        }

        if(StrUtil.isNotBlank(schedule.getWeek()+"")){
            chainWrapper.set(Schedule::getWeek, schedule.getWeek());
        }

        if(StrUtil.isNotBlank(schedule.getDate()+"")){
            chainWrapper.set(Schedule::getDate, schedule.getDate());
        }
        //2. 设置主键，并更新
        chainWrapper.eq(Schedule::getId, schedule.getId());
        boolean ret = chainWrapper.update();
        //3. 更新成功了，查询最最对象返回
        if(ret){
            return queryById(schedule.getId());
        }else{
            return schedule;
        }
    }

    @Override
    public boolean deleteById(Integer id) {
        return false;
    }


    /**
     * 查询当天老师给指定班级上课的课表
     * @param username 老师工号
     * @param cid   上课的班级
     * @return  指定班级上课的课表
     */
    @Transactional
    @Override
    public Schedule selectScheduleByCidAndDate(@Param("username") String username, @Param("cid")String cid){
        Schedule schedule = scheduleMapper.selectScheduleByCidAndDate(username, cid);
        if (schedule == null){
            throw new CustomException("0", "该班级暂无课程");
        }
        return schedule;
    }

    /**
     * 查询当天老师给班级上课的信息
     * @param teacherId 老师Id
     * @return 上课信息
     */
    @Override
    public List<StudentAttendanceRecord> selectScheduleByTeacherId(@Param("teacherId") String teacherId){
        List<StudentAttendanceRecord> studentAttendanceRecords = scheduleMapper.selectScheduleByTeacherId(teacherId);
        if (studentAttendanceRecords.size() <= 0){
            throw new CustomException("0", "暂无班级上课");
        }
        return studentAttendanceRecords;
    }


    /**
     * 查询所现在在上课的班级
     * @param username 用户表的主键id
     * @return
     */
    @Override
    public List<AttendanceData> selectClassesAll(String username) {

        //获取班级信息
        User user = userService.getbyUsername(username);
        List<AttendanceData> list = null;
        if (user!=null){
            list = scheduleMapper.selectClassesAll(user.getId()+"");
        }

        //查询班级人数
        list.forEach(l->{

            //Integer count = classInfoMapper.count(l.getCid());
            //设置人数和 班委信息
            Map<String, Object> objectMap = classInfoMapper.count(l.getCid());
            //老师考勤人数
            Integer teacherCount = scheduleMapper.selectRepeat(user.getId()+"");
            Integer count = Integer.valueOf(String.valueOf(objectMap.get("count")));
            if(null == objectMap.get("info") || Objects.isNull(objectMap.get("info"))){
                l.setCommittee("");
            }else{
                l.setCommittee(String.valueOf(objectMap.get("info")));
            }
            //记录在详情表的人数
            Integer recordsCount = scheduleMapper.selectCountBycid(l.getCid());
            if (recordsCount>0){
                l.setIsCommittee(true);
            }else{
                l.setIsCommittee(false);
            }
            //老师是否考勤过了，来确认学学委
            if (teacherCount>0){
                l.setIsTeacherCheck(true);
            }else{
                l.setIsTeacherCheck(false);
            }

            l.setStudentcount(count);
            //查询班级请假人数
            Integer leaveNum = leavereQuestsMapper.selectCountByCid(l.getCid());
            l.setLeavenum(leaveNum);

        });

        return list;
    }

    /**
     * 批量添加课程
     * @param inputStream
     * @return
     */
    @Override
    public void upload(InputStream inputStream) {
        //先判断是否先前有文件传输失败的情况而导致数据没有传输完毕的情况
        Object history = redisTemplate.opsForValue().get("line");
        int line = history == null ? 3 : (int) history;
        //创建数据集合
       schedulesList =new ArrayList<>();
        // 获取文件数据源
        List<Map<String, Object>> list = AlyExcelUtil.excelToShopIdList1(inputStream).get(0);
        //获取学年
        Map<String, Object> yearMap = list.get(0);
        for (Map.Entry<String, Object> yearSet : yearMap.entrySet()) {
            year = yearSet.getValue().toString();
            year = year.replaceAll(".+(\\d{4}-\\d{4}-\\d)","$1");
        }
        //解析数据
        for (int i = line; i < list.size(); i++,line++) {
            Map<String, Object> map = list.get(i);
            for (Map.Entry<String, Object> set : map.entrySet()) {
                //颜色数组
                String[] colorCodes =  {"#aaaaff", "#FDC123", "#D8F5AD", "#73E4CE", "#C8D14B", "#44C971", "#aaffff", "#00aaff", "#ffaaff", "#ffff7f", "#aaff7f", "#ffaa7f", "#7dffb8", "#ffc6c7", "#cbebff", "#ffb9ba"};
                //随机生成颜色
                Random random = new Random();
                int index = random.nextInt(colorCodes.length);
                randomColor = colorCodes[index];
                //创建一个课程对象
                if ("0".equals(set.getKey())){
                    //班级名称
                    String className = set.getValue().toString();
                    //班级编号
                    Integer id = classInfoMapper.selectIdByCname(className);
                    classId = id;
                }else{
                    //课程信息字符串
                    String str = set.getValue().toString();
                    String[] split = str.split("\n");
                    String teacherName = split[1];
                    //多个老师
                    if(teacherName.contains(",")){
                        String[] split1 = teacherName.split(",");
                        for (int i1 = 0; i1 < split1.length; i1++) {
                            teacherId = userMapper.selectIdByNickName1(split[i1]);
                            handelData(split);
                        }
                    }else {
                        teacherId = userMapper.selectIdByNickName1(teacherName);
                        handelData(split);
                    }
                }
            }
        }
        //添加数据
        if (schedulesList.size()>0){
            scheduleMapper.addList(schedulesList);
        }
    }

    /**
     * 处理数据
     * @param split
     */
    public void handelData(String split []){
        courseName = split[0];

        String weekAndClasstime = split[2];
        //星期
        week = weekAndClasstime.substring(0,1);
        //开始节次
        String timeStart =weekAndClasstime.substring(2,3);
        //结束节次
        String timeEnd = weekAndClasstime.substring(3,5);
        if (!"10".equals(timeEnd)){
            timeEnd = timeEnd = timeEnd.substring(1,2);
        }
        classtime = timeStart + "~" +timeEnd;
        //格式 体育 空字符串 日期与节次 数组长度为3
        if (courseName.contains("体育")&&split.length==3){
            classroom = "暂无教室";
            addCourseByTypeOf(weekAndClasstime);
        }
        else if (courseName.contains("体育")&&split.length==4){
            classroom = split[3];
            addCourseByTypeOf(weekAndClasstime);
            //大学英语 平常课与听力课
        }else if (split.length==8){
            //开始的周次
            if (weekAndClasstime.contains(",")){
                String weekAndClasstime1 = split[2];
                String weekAndClasstime2 = split[6];
                //第一次课
                String weekStart1 = weekAndClasstime1.substring(weekAndClasstime1.indexOf("(")+1,weekAndClasstime1.indexOf("-"));
                String weekEnd1 = weekAndClasstime1.substring(weekAndClasstime1.indexOf("-")+1,weekAndClasstime1.indexOf(","));

                final String[] s = weekAndClasstime1.split(",");
                String weekStart2 = s[1].replaceAll("(\\d{1,2}).+","$1");
                String weekEnd2 = "";
                if (s[1].substring(0,s[1].indexOf(")")).indexOf("-") == -1){
                    weekEnd2 = weekStart2;
                }else {
                    String[] split2 = s[1].split("-");
                    weekEnd2 = split2[1].replaceAll("(\\d{1,2}).+","$1");
                }
                if (weekAndClasstime1.contains("单周")){
                    //1代表单周
                    classroom = split[3];
                    addCourseToList(weekStart1,weekEnd1,"1");
                    addCourseToList(weekStart2,weekEnd2,"1");
                }else if (weekAndClasstime2.contains("双周")){
                    //1代表单周
                    classroom = split[3];
                    addCourseToList(weekStart1,weekEnd1,"2");
                    addCourseToList(weekStart2,weekEnd2,"2");
                }
                //第二次课
                String weekStart3 = weekAndClasstime2.substring(weekAndClasstime2.indexOf("(")+1,weekAndClasstime2.indexOf("-"));
                String weekEnd3 = weekAndClasstime2.substring(weekAndClasstime2.indexOf("-")+1,weekAndClasstime2.indexOf(","));
                final String[] split2 = weekAndClasstime2.split(",");
                String weekStart4 = weekAndClasstime2.substring(weekAndClasstime2.indexOf(",")+1,weekAndClasstime2.indexOf(",")+2);
                String weekEnd4 = "";
                if (split2[1].substring(0,split2[1].indexOf(")")).indexOf("-") == -1){
                    weekEnd4 = weekStart4;
                }else {
                    String[] split3 = split2[1].split("-");
                    weekEnd4= split3[1].replaceAll("(\\d{1,2}).+","$1");
                }
                if (weekAndClasstime2.contains("单周")){
                    //1代表单周
                    classroom = split[7];
                    addCourseToList(weekStart3,weekEnd3,"1");
                    addCourseToList(weekStart4,weekEnd4,"1");
                }else if (weekAndClasstime2.contains("双周")){
                    //2代表双周
                    classroom = split[7];
                    addCourseToList(weekStart3,weekEnd3,"2");
                    addCourseToList(weekStart4,weekEnd4,"2");
                }
            }else{
                String weekStart = weekAndClasstime.substring(weekAndClasstime.indexOf("(")+1,weekAndClasstime.indexOf("-"));
                String weekEnd = weekAndClasstime.substring(weekAndClasstime.indexOf("-")+1,weekAndClasstime.indexOf("-")+2);
                addCourseToList(weekStart,weekEnd);
            }
        }else {
            classroom = split[3];
            addCourseByTypeOf(weekAndClasstime);
        }
    }

    /**
     * 根据数据类型来添加课程
     * @param weekAndClasstime
     */
    public void addCourseByTypeOf(String weekAndClasstime){
        //开始的周次
        if (weekAndClasstime.contains(",")){
            //30102 (2-7,9-18周)(01-02节)
            String weekStart1 = weekAndClasstime.substring(weekAndClasstime.indexOf("(")+1,weekAndClasstime.indexOf("-"));
            String weekEnd1 = weekAndClasstime.substring(weekAndClasstime.indexOf("-")+1,weekAndClasstime.indexOf(","));
            String weekStart2 = weekAndClasstime.substring(weekAndClasstime.indexOf(",")+1,weekAndClasstime.indexOf(",")+2);
            String weekEnd2= "";
            String str = weekAndClasstime.split(",")[1];
            if (str.indexOf("-")!=-1){
                weekEnd2 = str.split("-")[1].replaceAll("(\\d{1,2}).+","$1");
            }else {
                weekEnd2 = str.replaceAll("(\\d{1,2}).+","$1");
            }
            addCourseToList(weekStart1,weekEnd1);
            addCourseToList(weekStart2,weekEnd2);
        }else{
            String weekStart = weekAndClasstime.replaceAll(".+\\((\\d+)\\-\\d+周.+", "$1");
            //结束的周次
            String weekEnd = weekAndClasstime.replaceAll(".+(\\d)\\-(\\d+)周.+", "$2");
            addCourseToList(weekStart,weekEnd);
        }
    }


    /**
     * 添加课程到数据集合中
     * @param weekStart
     * @param weekEnd
     */
    private void addCourseToList(String weekStart ,String weekEnd){
        Integer size = scheduleMapper.selectSchedulesByClassIdAndName(classId, courseName,classroom);
        //课程存在
        if (size != 0 || teacherId == null || classId == null){
            return;
        }
        int k = Integer.parseInt(weekStart);
        int k1 = Integer.parseInt(weekEnd);
        for (;k <= k1; k++) {
            Schedule schedule = new Schedule();
            schedule.setClassid(classId+"");
            schedule.setTeacherid(teacherId);
            schedule.setCoursename(courseName);
            schedule.setClassroom(classroom);
            schedule.setClasstime(classtime);
            schedule.setColour(randomColor);
            //根据开始周次获取上课的日期
            List<String> timeList = schoolYearMapper.selectDateByWeek(String.valueOf(k),year);
            //2022-12-20
            String time = timeList.get(Integer.valueOf(week)-1);
            String date  = calculateDate(time, classtime);
            schedule.setDate(date);
            String oddevenWeek = "";
            if (k%2 ==0 ){
                oddevenWeek = "双周";
            }else {
                oddevenWeek = "单周";
            }
            schedule.setWeek(k);
            schedule.setOddevenweek(oddevenWeek);
            schedule.setId(null);
            //课程不存在，则添加课程
            schedulesList.add(schedule);
            if (schedulesList.size()>=500){
                scheduleMapper.addList(schedulesList);
                schedulesList.clear();
            }
        }
    }

    /**
     * 对英语课程的特殊处理
     * @param weekStart
     * @param weekEnd
     */
    private void addCourseToList(String weekStart,String weekEnd,String flag){
        Integer size = scheduleMapper.selectSchedulesByClassIdAndName(classId, courseName,classroom);
        //课程存在
        if (size != 0 || teacherId == null || classId == null){
            return;
        }
        int k = Integer.parseInt(weekStart);
        int k1 = Integer.parseInt(weekEnd);
        for (;k <= k1; k++) {
            Schedule schedule = new Schedule();
            schedule.setClassid(classId+"");
            schedule.setTeacherid(teacherId);
            schedule.setCoursename(courseName);
            schedule.setClassroom(classroom);
            schedule.setClasstime(classtime);
            schedule.setColour(randomColor);
            //根据开始周次获取上课的日期
            List<String> timeList = schoolYearMapper.selectDateByWeek(String.valueOf(k),year);
            //2022-12-20
            String time = timeList.get(Integer.valueOf(week)-1);
            String date  = calculateDate(time, classtime);
            schedule.setDate(date);
            schedule.setWeek(k);
            //双周
            if (k%2 ==0){
                schedule.setOddevenweek("双周");
            }else{
                schedule.setOddevenweek("单周");
            }

            schedule.setId(null);
            //课程不存在，则添加课程
            if ("1".equals(flag) && k%2 !=0){
                schedulesList.add(schedule);
            }else if("2".equals(flag) && k%2 ==0){
                schedulesList.add(schedule);
            }
        }
    }


    @Override
    public List<ScheduleVo> findSystemUerTodayAllSchedule(String username) {
        List<ScheduleVo> list = scheduleMapper.findSystemUerTodayAllSchedule(username);
        if(null == list || list.isEmpty()){
            return Collections.emptyList();
        }
        //处理合班上课
        Map<String,ScheduleVo> voMap = new HashMap<>();
        for (ScheduleVo scheduleVo : list) {
            String key = scheduleVo.getCoursename()+"-"+scheduleVo.getClassroom()+"-"+scheduleVo.getClasstime();
            if (voMap.get(key) == null) {
                voMap.put(key,scheduleVo);
            }else{
                ScheduleVo vo = voMap.get(key);
                vo.setCname(vo.getCname()+"/"+scheduleVo.getCname());
                vo.setIds(vo.getId()+","+scheduleVo.getId());
                vo.setStuCount(vo.getStuCount()+scheduleVo.getStuCount());
                //看是否已经考过勤
                if(StringUtils.isNotEmpty(vo.getInfo()) && StringUtils.isNotBlank(vo.getInfo())){
                    String[] split = vo.getInfo().split(",");
                    String[] split1 = scheduleVo.getInfo().split(",");
                    vo.setInfo(Integer.valueOf(split[0])+Integer.valueOf(split1[0])+"");
                    vo.setAttId(split[1]+","+split1[1]);
                }
                voMap.put(key,vo);
            }
        }
        list = new ArrayList<>();
        for (Map.Entry<String, ScheduleVo> entry : voMap.entrySet()) {
            list.add(entry.getValue());
        }
        return list;
    }
}
